package com.ratingbay.console.service;

import java.sql.Timestamp;
import java.util.*;

import org.springframework.data.domain.*;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;

import com.ratingbay.console.dataface.*;
import com.ratingbay.console.dataimpl.*;
import com.ratingbay.console.dao.*;
import com.ratingbay.console.model.*;
import com.ratingbay.console.naivequery.*;

public class TweetServiceImpl extends BaseService implements ITweetService {
	public TweetDAO tweetDao = null;
	public TweetDAO getTweetDao() {
		return tweetDao;
	}
	public void setTweetDao(TweetDAO tweetDao) {
		this.tweetDao = tweetDao;
	}
	
	public GameSummaryDAO gameSummaryDao = null;
	public GameSummaryDAO getGameSummaryDao() {
		return gameSummaryDao;
	}
	public void setGameSummaryDao(GameSummaryDAO gameSummaryDao) {
		this.gameSummaryDao = gameSummaryDao;
	}
	
	@Override
	public Long findGameCountByUser(Long tUserId){
		return this.tweetDao.findGameCountByUser(tUserId);
	}

	@Override
	public Long findCountByGame(Long idGame){
		return this.gameSummaryDao.findCountByGame(idGame);
	}

	@Override
	public List<Tweet> findRecentTweets(Date begin,Date end) {
		Timestamp starttimestamp = new Timestamp(begin.getTime());
		Timestamp endtimestamp = new Timestamp(end.getTime());
		return this.tweetDao.findRecentTweets(starttimestamp,endtimestamp);
	}

	@Override
	public List<Tweet> findPopularTweets(Date from, Date to) {

		Timestamp starttimestamp = new Timestamp(from.getTime());
		Timestamp endtimestamp = new Timestamp(to.getTime());
		return this.tweetDao.findPopularTweets(starttimestamp, endtimestamp);
	}

	@Override
	public Page<Tweet> findTweetsByUserId(Date from, Date to, Long twitterUserId,
			int pageNum, int pageSize) {
		Timestamp starttimestamp = new Timestamp(from.getTime());
		Timestamp endtimestamp = new Timestamp(to.getTime());
		final PageRequest tweetsuserpage = new PageRequest(pageNum, pageSize, new Sort(new Order(Direction.DESC, "createDate")));
		return this.tweetDao.findByUserIdAndCreateDateBetween(starttimestamp, endtimestamp, twitterUserId, tweetsuserpage);
	}

	@Override
	public Page<Tweet> findTweetsByUserIds(List<Long> tUserIds, Date from,
			Date to, int pageNum, int pageSize) {
		Timestamp starttimestamp = new Timestamp(from.getTime());
		Timestamp endtimestamp = new Timestamp(to.getTime());
		final PageRequest tweetsuserpage = new PageRequest(pageNum, pageSize, new Sort(new Order(Direction.DESC, "createDate")));
		return this.tweetDao.findByUserIdInAndCreateDateBetween(starttimestamp, endtimestamp, tUserIds, tweetsuserpage);
	}

	@Override
	public Page<Tweet> findPopularTweetsByGame(Long idGame, Date from, Date to,
			int pageNum, int pageSize) {
		Timestamp starttimestamp = new Timestamp(from.getTime());
		Timestamp endtimestamp = new Timestamp(to.getTime());
		//final PageRequest tweetsuserpage = new PageRequest(pageNum, pageSize, new Sort(new Order(Direction.DESC, "retweetCount")));
		Page<Tweet> listToPage;
		List<Tweet> list = this.tweetDao.findByLIdGameAndCreateDateBetweenOrderByRetweetCount(idGame, starttimestamp, endtimestamp, pageSize,pageNum);
     		listToPage = new PageImpl<Tweet>(list);
		return listToPage;
	}
	
	@Override
	public Page<Tweet> findPositiveTweetsByGame(Long idGame, Date from, Date to,
			int pageNum, int pageSize) {
		Timestamp starttimestamp = new Timestamp(from.getTime());
		Timestamp endtimestamp = new Timestamp(to.getTime());
		//final PageRequest tweetsuserpage = new PageRequest(pageNum, pageSize, new Sort(new Order(Direction.DESC, "sentimentProbability")));
		Page<Tweet> listToPage;
		List<Tweet> list;
		list = this.tweetDao.findByIdGameAndCreateDateBetweenOrderBySentimentProbabilityDesc(idGame, starttimestamp,
			endtimestamp, pageSize,pageNum);
		listToPage = new PageImpl<Tweet>(list);
		return listToPage;
	}

	@Override
	public Page<Tweet> findNegativeTweetsByGame(Long idGame,  Date from, Date to,
			int pageNum, int pageSize) {
		Timestamp starttimestamp = new Timestamp(from.getTime());
		Timestamp endtimestamp = new Timestamp(to.getTime());
		//final PageRequest tweetsuserpage = new PageRequest(pageNum, pageSize, new Sort(new Order(Direction.ASC, "sentimentProbability")));
		Page<Tweet> listToPage;
		List<Tweet> list;
		list = this.tweetDao.findByIdGameAndCreateDateBetweenOrderBySentimentProbabilityAsc(idGame, starttimestamp, endtimestamp, pageSize,pageNum);
		listToPage = new PageImpl<Tweet>(list);
		return listToPage;
	}

	@Override
	public Page<Tweet> findLatestTweetsByGame(Long idGame,  Date from, Date to,
			int pageNum, int pageSize) {
		Timestamp starttimestamp = new Timestamp(from.getTime());
		Timestamp endtimestamp = new Timestamp(to.getTime());
		//final PageRequest tweetsuserpage = new PageRequest(pageNum, pageSize, new Sort(new Order(Direction.DESC, "createDate")));
		Page<Tweet> listToPage;
		List<Tweet> list;
		list = this.tweetDao.findByIdGameAndCreateDateBetweenOrderByCreateDate(idGame, starttimestamp, endtimestamp, pageSize,pageNum);
		listToPage = new PageImpl<Tweet>(list);
		return listToPage;
	}

	@Override
	public Page<Tweet> findUsersTweetsByGameAndUsers(Long idGame, List<Long> tUserIds, int pageNum, int pageSize) {
		Page<Tweet> pageTweets = new PageImpl<Tweet>(new ArrayList<Tweet>());
		if(tUserIds.size() < 1){
			return pageTweets;
		}
		List<Tweet> listTweets = new ArrayList<Tweet>();
		List<Long> list = TweetNaiveQuery.getInstance().findByIdGameAndUser(idGame, tUserIds ,pageSize,pageNum);
		for(Long l : list){
			Tweet ll = this.tweetDao.findById(l).get(0);
			listTweets.add(ll);
		}
		
		pageTweets = new PageImpl<Tweet>(listTweets);
		return pageTweets;
	}

	@Override
	public Page<IGamePlayer> findGamersByUserIds(List<Long> tUserIds, int pageNum, int pageSize){
		PageRequest pageRequest = new PageRequest(pageNum, pageSize);
		int totalGamers = tUserIds.size();
		
		int start = pageNum*pageSize;
	    int end = (pageNum+1)*pageSize;
		if(start > totalGamers)return null;

		List<Long> pagedTUserIds = null; 
		if(end > totalGamers){
			pagedTUserIds = tUserIds.subList(start, totalGamers);
		}else{
			pagedTUserIds = tUserIds.subList(start, end);
		}

		List<IGamePlayer> iGamersOfList = new ArrayList<IGamePlayer>();
		if(pagedTUserIds.size() > 1){
			List<Object[]> gamersOfList = 
				TweetNaiveQuery.getInstance().findGamersByUserIds(pagedTUserIds);
			Iterator<Object[]> it = gamersOfList.iterator();
			
			Object[] gamerOne;
			while(it.hasNext()){
				gamerOne = it.next();

				GamePlayerImpl gamePlayerImpl = new GamePlayerImpl();
				gamePlayerImpl.setGameCount( (Long)gamerOne[0] );
				gamePlayerImpl.setUserId( (Long)gamerOne[1] );
				gamePlayerImpl.setUsername( (String)gamerOne[2] );
				gamePlayerImpl.setProfileImageURL( (String)gamerOne[3] );

				iGamersOfList.add(gamePlayerImpl);
			}
		}
		
		Page<IGamePlayer> iGamersOfPage = 
			new PageImpl(iGamersOfList, pageRequest, (long)totalGamers);
		return iGamersOfPage;
	}

    @Override
	public List<Tweet> getTweetsByLinkAndUsers(Long linkId, List<Long> tUserIds, int pageNum, int pageSize){
		if(null == tUserIds || tUserIds.size() < 1){
			return new ArrayList<Tweet>();
		}
	    PageRequest pageRequest = new PageRequest(pageNum, pageSize);
	    Page<Tweet> pageOfTweet  = this.tweetDao.findTweetsByLinkAndUsers(linkId, tUserIds ,pageRequest);
	    return pageOfTweet.getContent();
	}

	@Override
	public List<Tweet> getTweetsByLink(Long linkId, int pageNum, int pageSize){
		return this.tweetDao.findTweetsByLink(linkId ,pageNum, pageSize);
	}
}
